package com.wz.project.system.dayReport.service.impl;

import com.wz.common.exception.BusinessException;
import com.wz.common.utils.DateUtils;
import com.wz.common.utils.StringUtils;
import com.wz.project.system.config.service.IConfigService;
import com.wz.project.system.dayReport.entity.DayReport;
import com.wz.project.system.dayReport.repository.DayReportDao;
import com.wz.project.system.dayReport.service.DayReportService;
import com.wz.project.system.employee.domain.Employee;
import com.wz.project.system.employee.service.EmployeeService;
import com.wz.project.system.post.service.IPostService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service("report")
public class DayReportServiceImpl implements DayReportService {

    private static final Logger log = LoggerFactory.getLogger(DayReportServiceImpl.class);

    @Autowired
    private DayReportDao dao;
    @Autowired
    private IConfigService configService;
    @Autowired
    private EmployeeService employeeService;
    @Autowired
    private IPostService postService;

    @Autowired
    private DayReportService dayReportService;


    @Override
    public void save(DayReport day_report) {
        dao.save(day_report);
    }

    @Override
    public void update(DayReport dayReport) {
        dao.save(dayReport);
    }

    @Override
    public void deleteById(String ids) {
        for (String s : ids.split(",")) {
            dao.deleteById(Integer.valueOf(s));
        }
    }

    @Override
    public Page<DayReport> findAllByParam(DayReport dayReport, Integer pageNum, Integer pageSize) {
        //查询条件构造
        Pageable pageable = PageRequest.of(pageNum - 1, pageSize);
        Specification<DayReport> spec = new Specification<DayReport>() {
            private static final long serialVersionUID = 1L;

            @Override
            public Predicate toPredicate(Root<DayReport> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                String startDate = ("1970-01-01 00:00:00");
                String endTime = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date());
                Predicate p1 = null;
                Predicate p2 = null;
                Predicate p3 = null;
                Predicate p7 = null;
                Predicate p8 = null;
                if (!StringUtils.isEmpty(dayReport.getStaffName())) {
                    p1 = cb.like(root.get("staffName"), "%" + dayReport.getStaffName() + "%");
                } else {
                    p1 = cb.like(root.get("staffName"), "%%");
                }
                if (!StringUtils.isEmpty(dayReport.getStaffStation())) {
                    p2 = cb.like(root.get("staffStation"), "%" + dayReport.getStaffStation() + "%");
                } else {
                    p2 = cb.like(root.get("staffStation"), "%%");
                }
                if (!StringUtils.isEmpty(dayReport.getStaffStatus())) {
                    p3 = cb.like(root.get("staffStatus"), "%" + dayReport.getStaffStatus() + "%");
                } else {
                    p3 = cb.like(root.get("staffStatus"), "%%");
                }
                if (!StringUtils.isNull(dayReport.getStartTime())) {
                    p7 = cb.greaterThan(root.get("startTime"), dayReport.getStartTime());
                } else {
                    p7 = cb.greaterThan(root.get("startTime"), DateUtils.parseDate(startDate));
                }
                if (!StringUtils.isNull(dayReport.getUpdateTime())) {
                    p8 = cb.lessThan(root.get("startTime"), dayReport.getUpdateTime());
                } else {
                    p8 = cb.lessThan(root.get("startTime"), new Date());
                }
                query.where(p1, p2, p3, p7, p8);
                return null;
            }
        };

        return dao.findAll(spec, pageable);
    }

    @Override
    public List<DayReport> findAllByParam(DayReport dayReport) {
        String startDate = ("1970-01-01 00:00:00");
        String endTime = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date());
        return dao.findAll(StringUtils.isEmpty(dayReport.getStaffName()) ? "" : dayReport.getStaffName()
                , StringUtils.isEmpty(dayReport.getStaffStation()) ? "" : dayReport.getStaffStation()
                , StringUtils.isEmpty(dayReport.getStaffStatus()) ? "" : dayReport.getStaffStatus()
                , StringUtils.isNull(dayReport.getStartTime()) ? startDate : dayReport.getStartTime()
                , StringUtils.isNull(dayReport.getUpdateTime()) ? endTime : dayReport.getUpdateTime());
    }

    @Override
    public List<DayReport> findAllByParamGroup(DayReport dayReport) {
        String startDate = ("1970-01-01 00:00:00");
        String endTime = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date());
        ArrayList<DayReport> dayReports = new ArrayList<>();
        List<DayReport> allGroup = dao.findAllGroup(StringUtils.isEmpty(dayReport.getStaffName()) ? "" : dayReport.getStaffName()
                , StringUtils.isEmpty(dayReport.getStaffStation()) ? "" : dayReport.getStaffStation()
                , StringUtils.isEmpty(dayReport.getStaffStatus()) ? "" : dayReport.getStaffStatus()
                , StringUtils.isNull(dayReport.getStartTime()) ? startDate : dayReport.getStartTime()
                , StringUtils.isNull(dayReport.getUpdateTime()) ? endTime : dayReport.getUpdateTime());
        if (allGroup != null && allGroup.size() > 1) {
            int i=0;
            do {
                dayReports.add(allGroup.get(i));
                if (i<allGroup.size()-1 &&!allGroup.get(i).getStaffName().equals(allGroup.get(i + 1).getStaffName())){
                        dayReports.add(new DayReport());
                    }
                i++;
            }while (i <= allGroup.size()-1);

        }
        return dayReports;
    }


    @Override
    public DayReport findById(Integer id) {
        return dao.findById(id).get();
    }

    /**
     * 导入用户数据
     *
     * @param dayReportList   日报数据列表
     * @param isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
     * @return 结果
     */
    @Override
    public String importDayReport(List<DayReport> dayReportList, boolean isUpdateSupport) {
        if (StringUtils.isNull(dayReportList) || dayReportList.size() == 0) {
            throw new BusinessException("导入数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (DayReport dayReport : dayReportList) {
            try {
                if (StringUtils.isNull(dayReport)) {
                    this.save(dayReport);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "导入成功");
                } else if (isUpdateSupport) {
                    this.update(dayReport);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "更新成功");
                } else {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "已存在");
                }
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new BusinessException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    @Override
    public void pushReport() {
        List<Employee> employeeList = employeeService.selectEmployeeList(new Employee());
        for (Employee employee : employeeList) {
            int count = dayReportService.findByStartTimeCount(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")), employee.getName());
            if (count != 0) {
                continue;
            }
            DayReport dayReport = new DayReport();
            dayReport.setStaffName(employee.getName());  //员工姓名
            dayReport.setStaffStation(employeeService.selectPostByEmployee(employee.getEmployeeId()).get(0).getPostName()); //岗位
            dayReport.setStartTime(new Date());  //日报创建时间
            Long postId = employeeService.selectPostByEmployee(employee.getEmployeeId()).get(0).getPostId();
            if (postId != null) {
                //如果当前员工不是总监、董事长、总经理等
                if (postId != 6 && postId != 1 && postId != 2 && postId != 3) {
                    if (employee.getStatus() == 1) {
                        dayReport.setStaffStatus("在岗");
                        dao.save(dayReport);
                    } else if (employee.getStatus() == 2) {
                        dayReport.setStaffStatus("离职");

                    } else if (employee.getStatus() == 3) {
                        dayReport.setStaffStatus("请假");
                        dao.save(dayReport);
                    } else {
                        dayReport.setStaffStatus("出差");
                        dao.save(dayReport);
                    }
                }
            }
        }
        System.out.println("开始推送日报");
    }

    @Override
    public int findByStartTimeCount(String format, String name) {
        return dao.findByStartTimeCount(format, name);
    }

    @Override
    public List<String> findFlagByName(String name) {


        return null;
    }
}
